package com.hot12345.database;

import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.List;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.hot12345.server.DBConnection.TianyaDBConnectionProvider;
import com.hot12345.server.cache.Cache;
import com.hot12345.server.cache.CacheObject;
import com.hot12345.server.cache.KeyGenerater;
import com.hot12345.server.cache.TianyaCacheManager;
 
/** 
 * <p>
 * Title:
 * </p>
 *  
 * <p> 
 * Description:
 * </p>
 *      
 * <p>
 * Copyright: Copyright (c) 2005
 * </p>
 *
 * <p>
 * Company:
 * </p>
 *   
 * @author  
 * @version 1.0
 */
public class CommonDAO {
	
	private static Log logger = LogFactory.getLog(CommonDAO.class);
    /**
     *  
     *
     * @param dbID
     *            String
     * @param sql
     *            String
     * @param isCache
     *            boolean: 
     * @param key
     *            Object:  
     * @return List
     */
    public List get(String dbID, String sql,Object[] params, boolean isCache,
                    long lifeTimestamp, Object key) throws Exception {       
        if (isCache) {
           return getFromCache(dbID,sql, params,key,lifeTimestamp);
        } else {
             
            // list = this.getListFromDB(dbID, sql);
            DBDataProvider dBDataProvider = new DBDataProvider();
            return dBDataProvider.getMapFromDB(dbID, sql, params);
        }

    }

    private List getFromCache(String dbID, String sql,Object[] params, Object key,long lifeTimestamp)throws Exception{
        List list = null;
        Cache cache = TianyaCacheManager.getCache(dbID);
        if (key == null || key.equals("")) { 
            key = KeyGenerater.generateSQLKey(sql, "GB2312");
        }
        CacheObject cacheObject = cache.getCacheObject(key);
        if (cacheObject != null && !cache.isExpiredEntries(cacheObject)) {
            
            return (List) cacheObject.object;
        } else if (cacheObject == null) {
             
            DBDataProvider dBDataProvider = new DBDataProvider();
            list = dBDataProvider.getMapFromDB(dbID, sql,  params);
            if (list != null &&list.size() > 0) {
                cache.add(key, list, lifeTimestamp);  
            }
            return list;
        } else { //end of cacheObject == null 
            cacheObject.state = false; 
            //test
            GetDataThread getDataThread = new GetDataThread(dbID, sql, params,key,
                    lifeTimestamp);
            getDataThread.start();
             
            return (List) cacheObject.object;

        }
    }
    /**
     *  
     *
     * @param dbID
     *            String
     * @param sql
     *            String
     * @param isCache
     *            boolean: 
     * @param key
     *            Object: 
     * @return List
     */

    public void delete(String dbID, String sql, Object[] params,Object key) throws Exception{
        if (key == null || key.equals("")) {
            key = KeyGenerater.generateSQLKey(sql, "GB2312");
        }
        
        this.deleteFromDB(dbID, sql,params);
        if (key != null) {
            
            TianyaCacheManager.getCache(dbID).remove(key);
        }
    }

    /**
     *  
     *
     * @param cacheableObject
     *            Cacheable
     * @return Cacheable
     */
    private int deleteFromDB(String dbID, String sql,Object[] params) throws Exception{
    	/**
        Connection con = null;
        Statement stmt = null;

        try {
            con = TianyaDBConnectionProvider.getConnection(dbID);
            stmt = con.createStatement();
            stmt.executeUpdate(sql);
        } catch (SQLException ex) {
             
            return false;
        } finally {
            try {
                if (stmt != null) {
                    stmt.close();
                }
                if (con != null) {
                    con.close();
                    // TianyaDBConnectionProvider.freeconn(con);
                }

            } catch (Exception e) {
                //e.printStackTrace();
            }

        }
        return true;
        */
    	
    	return this.update(dbID, sql,params);
    }

    /**
     *  
     *
     * @param sql
     *            String
     * @param dbID
     *            String
    
    public long save(String dbID, String sql) {
        return this.saveToDB(dbID, sql);
         
    }
 */
 
    public int update(String dbID, String sql,Object[] params) throws Exception{
        Connection con = null;
        Statement stmt = null;
        PreparedStatement ps=null;
        // long id = 0;
        try {
            // System.out.println(sql);
        	con = TianyaDBConnectionProvider.getConnection(dbID);
          //  con = TianyaDBConnectionProvider.getConnection(dbID);
           // stmt = con.createStatement();
            int num = 0;
        
              ps = con.prepareStatement(sql);
              int index = 1;
              if (params != null) {
                int n=params.length;
                if (n < 2 || n % 2 != 0 || (n/2)!=this.getStrNum(sql,"?")) {
                  throw new IllegalArgumentException(
                      "����Ϊ������߲�������");
                }
                for (int i = 0; i < params.length; i += 2) {

                  params[i+1]=this.pareObjToStr(params[i+1]);

                  if ( ( (String) params[i]).toLowerCase().equals("string")) {
                    ps.setString(index++, (String) params[i + 1]);
                  }
                  if ( ( (String) params[i]).toLowerCase().equals("long")) {
                    ps.setLong(index++, Long.parseLong( (String) params[i + 1]));
                  }
                  if ( ( (String) params[i]).toLowerCase().equals("int")) {
                    ps.setInt(index++, Integer.parseInt( (String) params[i + 1]));
                  }
                  if ( ( (String) params[i]).toLowerCase().equals("date")) {
                   ps.setString(index++, (String) params[i + 1]);
                  }
                  if ( ( (String) params[i]).toLowerCase().equals("float")) {
                    ps.setFloat(index++, Float.parseFloat((String) params[i + 1]));
                  }
                  if ( ( (String) params[i]).toLowerCase().equals("double")) {
                    ps.setDouble(index++, Double.parseDouble((String) params[i + 1]));
                  }

                  if ( ( (String) params[i]).toLowerCase().equals("image")) {
                    ps.setBytes(index++, (byte[]) params[i + 1]);

                  }
                }
              }
            
              return ps.executeUpdate();
            
            //return stmt.executeUpdate(sql);
        } catch (Exception ex) {
             ex.printStackTrace();
            //  
            return -1;
        } finally { 

            try {
                if (stmt != null) {
                    stmt.close();
                }
                if (con != null) {

                    con.close();
                    // TianyaDBConnectionProvider.freeconn(con);
                }

            } catch (Exception e) {
            	logger.error("Exception", e);
            }
        }

    }

    
     
    
    /**
     *  
     * 
     * @param cacheableObject
     *            Cacheable
     * @return Cacheable
    
    private long saveToDB(String dbID, String sql) {
        Connection con = null;
        PreparedStatement pst = null;
        CallableStatement cs = null;
        long id = 0;
        try {
            System.out.println(sql);
            con = TianyaDBConnectionProvider.getConnection(dbID);
            cs = con.prepareCall(sql);

            // / 
            // String sql = " {call
            // sp_PublicForum_Compose_Culture_new('culture','writer','title','content',10,'127.0.0.1',?)}";
            //  
            // CREATE PROCEDURE sp_PublicForum_Compose_Culture_new
            // @stritem varchar(50),
            // @strWriter varchar(16),
            // @strTitle varchar(80),
            // @txtContent text,
            // @intContentLen int = 0,
            // @strIP char(15),
            // @iden int output
            //
            //
            // AS
            // --declare @iden int
            //
            // if @stritem='culture'
            // begin
            // INSERT INTO bbs_culture_title (writer,title,content,size,IP)
            // VALUES(@strWriter,@strTitle,@txtContent,@intContentLen,@strIP)
            //
            // SELECT @iden = @@identity FROM bbs_culture_title
            // end
            //
            // GO

            cs.registerOutParameter(1, java.sql.Types.BIGINT);
            cs.execute();
            id = cs.getLong(1);

        } catch (Exception ex) {
            //   ex.printStackTrace();
            //  
            return -1;
        } finally {

            try {
                if (cs != null) {
                    cs.close();
                }
                if (con != null) {

                    con.close();
                    // TianyaDBConnectionProvider.freeconn(con);
                }

            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return id;
    }
 */
    /**
     *  
     *
     * @param sql
     *            String
     * @param dbID
     *            String
     */
    public boolean update(String dbID, String sql) {
        return this.updateToDB(dbID, sql);
    }

    /**
     *  
     *
     * @param cacheableObject
     *            Cacheable
     * @return Cacheable
     */
    private boolean updateToDB(String dbID, String sql) {
        
        Connection con = null;
        Statement stmt = null;
        ResultSet rs = null;
        try {
        	con = TianyaDBConnectionProvider.getConnection(dbID);
           // con = TianyaDBConnectionProvider.getConnection(dbID);
            CallableStatement cs = con.prepareCall(sql);
            cs.executeUpdate();
        } catch (SQLException ex) {
            //  ex.printStackTrace();
            return false;
        } catch (Exception e) {
			// TODO Auto-generated catch block
			logger.error("Exception",e);
		} finally {

            try {

                if (stmt != null) {
                    stmt.close();
                }
                if (con != null) {
                    // TianyaDBConnectionProvider.freeconn(con);
                    con.close();
                }

            } catch (Exception e) {
                logger.error("Exception",e);
            }

        }
        return true;
    }

 
	  private int getStrNum(String sql,String str) {
	    int num = 0;
	    int index = sql.indexOf(str);
	    while (index != -1) {
	      num++;
	      index=sql.indexOf(str,index+str.length());
	    }
	    return num;
	  }
	  
	  
	  /**
	   * 把Object类型对象按照相应的类型进行转换，返回String类型
	   * @param obj
	   * @return 返回String类型
	   */
	  private String pareObjToStr(Object obj){
	    if(obj==null)
	      return null;
	    if(obj instanceof String)
	      return obj.toString();
	    if(obj instanceof Integer)
	      return ((Integer)obj).toString();
	    if(obj instanceof Long)
	      return ((Long)obj).toString();
	    if(obj instanceof Float)
	      return ((Float)obj).toString();
	    if(obj instanceof Double)
	      return ((Double)obj).toString();
	    if(obj instanceof java.util.Date)
	      return new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format((java.util.Date)obj);

	    return obj.toString();
	  }

}
